﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Net;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using QT.Windows.Shell;

namespace UrlChecker.Setting
{
    public partial class URLManage : GlassForm
    {
        #region Attributes

        private string txtFileName = "";
        private string currentGroup = "";
        private DataGridViewRowCollection rows = null;
        Regex regex = new Regex(@"http://([\w-]+\.)+[\w-]+(/[\w- ./?%&=]*)?", RegexOptions.IgnoreCase);
        
        private Thread myThread = null;
        private delegate void myDeleGateAddRow(DataGridViewRow row);
        private delegate void myDeleGateClearRow();
        private delegate string myDeleGategetComboBoxtxt();
        private delegate string myDeleGategetComboBoxvalue();
        private delegate void myDeleGateSetProgress(bool b, int index, int count, int skip);

        #endregion

        #region URLManage

        public URLManage()
        {
            InitializeComponent();
        }

        private void URLManage_Load(object sender, EventArgs e)
        {
            InitComboBox(1);
        }

        private void URLManage_SizeChanged(object sender, EventArgs e)
        {
            int panelX = (this.Width - this.pProgress.Width) / 2;
            int panelY = (this.Height - this.pProgress.Height) / 3;
            this.pProgress.Location = new Point(panelX, panelY);
        }

        private void URLManage_FormClosing(object sender, FormClosingEventArgs e)
        {
            e.Cancel = true;

            if (myThread != null && myThread.IsAlive)
            {
                if (MessageBox.Show("正在进行操作，确认要退出吗？", "系统提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
                {
                    return;
                }
                myThread.Abort();
            }

            e.Cancel = false;
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            this.statusStrip1.BackColor = AeroColor;
        }

        #endregion

        #region Event

        #region Button

        private void btnImport_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(this.cbbUrlGroup.SelectedValue.ToString()))
            {
                MessageBox.Show("请选择需要导入的分组");
                return;
            }

            if (MessageBox.Show("请确认要导入网址到分组 " + this.cbbUrlGroup.GetItemText(this.cbbUrlGroup.SelectedItem) + " 吗？", "系统提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.Cancel)
            {
                return;
            }

            DialogResult Result=DialogResult.OK;
            if (this.dgvUrlList.Rows.Count > 0)  Result = MessageBox.Show("是否清空现有网址数据（不删除统计结果）?", "系统提示", MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
            if (Result == DialogResult.Cancel) return;

            ReadData(Result == DialogResult.Yes ? true : false);
        }

        private void btnExport_Click(object sender, EventArgs e)
        {
            SaveFileDialog sfDialog = new SaveFileDialog();
            sfDialog.ValidateNames = true;
            sfDialog.Filter = "文本文件(*.txt)|*.txt";
            sfDialog.FilterIndex = 1;
            sfDialog.DefaultExt = "txt";
            sfDialog.FileName = "";
            sfDialog.AddExtension = true;
            if (sfDialog.ShowDialog() == DialogResult.Cancel)
            {
                return;
            }

            string strFilePath = sfDialog.FileName;
            sfDialog.Dispose();

            string message = "导出成功";
            try
            {
                QT.SEO.Export.Export2Txt(this.dgvUrlList, strFilePath);
            }
            catch(Exception ex)
            {
                message = "导出失败，错误信息：" + ex.Message;
            }
            finally
            {
            }

            MessageBox.Show(message);
        }

        private void btnAdd_Click(object sender, EventArgs e)
        {
            if (this.cbbUrlGroup.SelectedValue == null)
            {
                MessageBox.Show("系统错误：分组信息不能为NULL");
                return;
            }
            if (this.cbbUrlGroup.SelectedIndex == 0)
            {
                MessageBox.Show("请选择分组");
                return;
            }

            AddURL myAddURL = new AddURL(this.cbbUrlGroup.SelectedValue.ToString(), null);
            if(myAddURL.ShowDialog()==DialogResult.Cancel) return;
            cbbUrlGroup_SelectedIndexChanged(sender, e);
        }

        private void btnModify_Click(object sender, EventArgs e)
        {
            if(this.dgvUrlList.SelectedRows.Count==0)
            {
                MessageBox.Show("请选择要修改的网址");
                return;
            }

            List<string> guids = new List<string>();
            List<string> urls = new List<string>();
            foreach (DataGridViewRow row in this.dgvUrlList.SelectedRows)
            {
                guids.Add(row.Cells[2].Value.ToString());
                urls.Add(row.Cells[0].Value.ToString());
            }


            ModifyURL myURL = new ModifyURL(this.cbbUrlGroup.SelectedValue.ToString(), guids, string.Join(",", urls.ToArray()));
            if (myURL.ShowDialog() == DialogResult.Cancel) return;
            cbbUrlGroup_SelectedIndexChanged(sender, e);
        }

        private void btnDelete_Click(object sender, EventArgs e)
        {
            if (this.dgvUrlList.SelectedRows.Count == 0)
            {
                MessageBox.Show("请选择删除项");
                return;
            }

            if (MessageBox.Show("删除后不可恢复，请再次确认！", "系统提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.Cancel)
            {
                return;
            }

            List<string> guids = new List<string>();
            foreach (DataGridViewRow row in this.dgvUrlList.SelectedRows) guids.Add(row.Cells[2].Value.ToString());

            if (QT.SEO.URL.Delete(null, guids)<1)
            {
                MessageBox.Show("删除失败");
                return;
            }
            cbbUrlGroup_SelectedIndexChanged(sender, e);
            MessageBox.Show("删除已完成");
        }

        private void btnClear_Click(object sender, EventArgs e)
        {
            if (this.dgvUrlList.RowCount == 0) return;

            if (MessageBox.Show("清空后不可恢复，请再次确认！", "系统提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Warning) == DialogResult.Cancel)
            {
                return;
            }

            int rval = 0;

            try
            {
                if (string.IsNullOrEmpty(this.cbbUrlGroup.SelectedValue.ToString())) rval = QT.SEO.URL.Delete();
                else rval = QT.SEO.URL.Delete(this.cbbUrlGroup.SelectedValue.ToString());
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }

            if (rval < 1)
            {
                MessageBox.Show("操作失败");
                return;
            }
            else
            {
                cbbUrlGroup_SelectedIndexChanged(sender, e);
                MessageBox.Show("操作成功");
            }
        }

        #endregion

        #region ToolStripMenuItem

        private void contextMenuStrip1_Opening(object sender, CancelEventArgs e)
        {
            if (this.dgvUrlList.Rows.Count == 0) this.ToolStripMenuItem_Export.Enabled = false;
            else this.ToolStripMenuItem_Export.Enabled = true;

            if (this.dgvUrlList.SelectedRows.Count == 0) this.ToolStripMenuItem_Delete.Enabled = false;
            else this.ToolStripMenuItem_Delete.Enabled = true;
        }

        private void ToolStripMenuItem_Import_Click(object sender, EventArgs e)
        {
            btnImport_Click(sender, e);
        }

        private void ToolStripMenuItem_Export_Click(object sender, EventArgs e)
        {
            btnExport_Click(sender, e);
        }

        private void ToolStripMenuItem_Add_Click(object sender, EventArgs e)
        {
            btnAdd_Click(sender, e);
        }

        private void ToolStripMenuItem_Modify_Click(object sender, EventArgs e)
        {
            btnModify_Click(sender, e);
        }

        private void ToolStripMenuItem_Delete_Click(object sender, EventArgs e)
        {
            btnDelete_Click(sender, e);
        }

        private void ToolStripMenuItem_Clear_Click(object sender, EventArgs e)
        {
            btnClear_Click(sender, e);
        }

        private void ToolStripMenuItem_CheckURL_Click(object sender, EventArgs e)
        {
            rows = this.dgvUrlList.Rows;
            myThread = new Thread(new ThreadStart(ThreadCheckURL));
            myThread.Start();            
        }

        #endregion

        #region ComboBox

        private void cbbUrlGroup_SelectedIndexChanged(object sender, EventArgs e)
        {
            DataTable dt = null;

            try
            {
                switch (this.cbbUrlGroup.SelectedValue.ToString())
                {
                    case null:
                    case "":
                        dt = QT.SEO.URL.GetAll();
                        break;
                    default:
                        dt = QT.SEO.URL.GetAll(this.cbbUrlGroup.SelectedValue.ToString());
                        break;
                }

                this.dgvUrlList.AutoGenerateColumns = false;
                this.dgvUrlList.Columns[0].DataPropertyName = "url";
                this.dgvUrlList.Columns[1].DataPropertyName = "gname";
                this.dgvUrlList.Columns[2].DataPropertyName = "guid";
                this.dgvUrlList.DataSource = dt;
                this.dgvUrlList.AutoResizeColumns();
            }
            catch (ThreadAbortException)
            {
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
            }
        }

        #endregion

        #region Label

        private void lblGroup_Click(object sender, EventArgs e)
        {
            GroupManage myGroup = new GroupManage();
            myGroup.ShowDialog();
            myGroup.Dispose();
            int index = this.cbbUrlGroup.SelectedIndex;
            InitComboBox(index);
        }

        #endregion

        #region DataGridView

        private void dgvUrlList_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
        {
            this.tsslMsg.Text = string.Format("网址总数：{0}", this.dgvUrlList.RowCount);
        }
        
        private void dgvUrlList_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.RowIndex == -1) return;
            this.tsslPostion.Text = string.Format("     行：{0}     列{1}", e.RowIndex + 1, e.ColumnIndex + 1);
        }

        #endregion

        #endregion

        #region Method

        private void ReadData(bool b)
        {
            OpenFileDialog myOpenFileDialog = new OpenFileDialog();
            myOpenFileDialog.Title = "请选择包含网址的文本文件";
            myOpenFileDialog.Filter = "text file (*.txt;*.log)|*.txt;*.log|AllFiles (*.*)|*.*";
            if (DialogResult.Cancel == myOpenFileDialog.ShowDialog())
            {
                return;
            }

            if (b)
            {
                QT.SEO.URL.Delete(this.cbbUrlGroup.SelectedValue.ToString());
                this.dgvUrlList.Rows.Clear();
            }

            txtFileName=myOpenFileDialog.FileName;

            myThread = new Thread(new ThreadStart(ThreadImport));
            myThread.Start();
        }

        public void InitComboBox(int index)
        {
            DataTable dt = QT.SEO.Group.GetAll();
            DataRow dr = null;

            dr = dt.NewRow();
            dr["guid"] = "";
            dr["GName"] = "--全部--";
            dt.Rows.InsertAt(dr, 0);

            this.cbbUrlGroup.ValueMember = dt.Columns[0].ToString();
            this.cbbUrlGroup.DisplayMember = dt.Columns[1].ToString();
            this.cbbUrlGroup.DataSource = dt;

            this.cbbUrlGroup.SelectedIndex = index >= this.cbbUrlGroup.Items.Count ? 0 : index;
            currentGroup = getComboBoxtxt();
        }

        #endregion

        #region Thread

        private void ThreadImport()
        {
            FileStream ifs = null;
            StreamReader sr = null;

            try
            {
                ifs = new FileStream(txtFileName, FileMode.Open, FileAccess.Read);
                sr = new StreamReader(ifs);

                int mySkip = 0;

                string gid = getComboBoxvalue();
                int lineIndex = 0;

                while (!sr.EndOfStream)
                {
                    SetProgress(true, lineIndex, 0, mySkip);
                    string inputStr = sr.ReadLine();
                    //显示到DataGridView，写入数据库
                    if (QT.SEO.URL.Add(inputStr, gid) == -2)
                    {
                        mySkip++;
                        continue;
                    }

                    lineIndex++;
                }

                SetProgress(false, lineIndex, 0, mySkip);
                this.cbbUrlGroup_SelectedIndexChanged(new object(), new EventArgs());
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            finally
            {
                if (ifs != null) ifs.Dispose();
            }
        }

        private void ThreadCheckURL()
        {
            int failed = 0;
            int success = 0;
            int other = 0;
            int index=0;

            foreach (DataGridViewRow row in rows)
            {
                SetProgress(true, index, this.dgvUrlList.RowCount, 0);
                if (!regex.IsMatch(row.Cells[0].Value.ToString()))
                {
                    failed++;
                    row.DefaultCellStyle.ForeColor = Color.Red;
                    continue;
                }

                switch (QT.SEO.UrlGather.GetStatusCode(row.Cells[0].Value.ToString()))
                {
                    case HttpStatusCode.NotFound:
                        failed++;
                        row.DefaultCellStyle.ForeColor = Color.Red;
                        QT.SEO.URL.Delete(row.Cells[0].Value.ToString());
                        break;
                    case HttpStatusCode.OK:
                        success++;
                        row.DefaultCellStyle.ForeColor = Color.Black;
                        break;
                    default:
                        other++;
                        row.DefaultCellStyle.ForeColor = Color.Gray;
                        break;
                }
                index++;
            }

            SetProgress(false, index, this.dgvUrlList.RowCount, 0);
            MessageBox.Show(string.Format("检查完成,200：{0}；404：{1}；其他：{2}", success, failed, other));
        }

        private string getComboBoxtxt()
        {
            if (this.InvokeRequired)
            {
                return this.Invoke(new myDeleGategetComboBoxtxt(getComboBoxtxt)) as string;
            }
            else
            {
                return this.cbbUrlGroup.GetItemText(this.cbbUrlGroup.SelectedItem);
            }
        }

        private string getComboBoxvalue()
        {
            if (this.InvokeRequired)
            {
                return this.Invoke(new myDeleGategetComboBoxvalue(getComboBoxvalue)) as string;
            }
            else
            {
                return this.cbbUrlGroup.SelectedValue.ToString();
            }
        }

        private void SetProgress(bool b,int index,int count,int skip)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new myDeleGateSetProgress(SetProgress), new object[] { b, index, count, skip });
            }
            else
            {
                if (count == 0)
                {
                    this.pbProgress.Style = ProgressBarStyle.Marquee;
                    this.lblProgress.Text = string.Format("已导入{0}条数据，跳过{1}条已存在数据", index, skip);
                }
                else
                {
                    this.pbProgress.Style=ProgressBarStyle.Blocks;
                    this.pbProgress.Maximum = count;
                    this.pbProgress.Value = index;
                    this.lblProgress.Text = string.Format("已检查：{0}/{1}", index, count);
                }
                this.pProgress.Visible = b;
                this.pHead.Enabled = !b;
            }
        }

        #endregion
    }
}
